<script>
import axios from "axios";
import { useActiveElement } from '@vueuse/core'
import {watch} from "vue";

export default {
  data() {
    return {
      children: null,
      code: 200,
      path: "",
      loading: false,
      fileName: "",
      newName: "",
      paths: [],
      dialogFormVisible: false,
      dialogFormVisibleRename: false,
			srcFile: null,
			srcPath: null,
			selectFile: null,
      uploadHeaders: {
        "Content-Type": "multipart/form-data"
      },
			rowStyle: {
				"background-color": "red"
			},
			hasRowStyle: false,
      uploadPercent: 0,
      focusElement: null,
      progressStatus: "",
      pathStack: []
    }
  },
  methods: {
    childrenList() { //得到子节点列表
      this.loading = true
      axios.get("/api/children", {
        params: {
          path: this.path
        }
      }).then(resp => {
          this.children = resp.data.data
          this.code = resp.data.code
          this.loading = false
          if (this.code === 5101) {
            this.$message({
              message: resp.data.message,
              type: "warning"
            })
          }else if (this.code === 5400) {
            this.$message({
              message: "未登录",
              type: "error"
            })
            setTimeout(() => {
              this.$router.push("/")
            }, 3000) // 3s后跳转到登录页面
          }
        }
      ).catch(resp => {
        this.code = resp.data.code
        this.loading = false
        this.$message({
          message: "未知错误",
          type: "error"
        })
      })
      this.splitPath()
    },
    childrenListByIdx(idx) { //根据截取paths发送请求，获取字节点列表
      // console.log(this.paths.slice(0, idx + 1).join("/"))
      this.path = "/" + this.paths.slice(0, idx + 1).join("/")
      this.childrenList()
    },
    toDateString(row, column, milliseconds) { //毫秒数转字符串时间
      let date = new Date(milliseconds);
      let Y = date.getFullYear() + '-';
      let M = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) + '-' : date.getMonth() + 1 + '-';
      let D = date.getDate() < 10 ? '0' + date.getDate() + ' ' : date.getDate() + ' ';
      let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
      let m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
      let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
      return Y + M + D + h + m + s
    },
    toNumber(num) { //保留两位小数
      return num.toFixed(2)
    },
    backLastDirectory() { //回到上一级文件夹
      let idx = this.path.lastIndexOf("/");
      this.path = this.path.slice(0, idx);
      this.childrenList()
    },
    addDirectory() {
      this.dialogFormVisible = false
      axios.post("api/addDirectory", {
          path: this.path,
          fileName: this.fileName
      }).then(resp => {
        if (resp.data.code === 200) { //弹窗提示
          this.$message({
            message: "文件添加成功",
            type: "success"
          })
          this.childrenList()
        }else {
          this.$message({
            message: resp.data.message,
            type: "warning"
          })
        }
      }).catch(resp => {
        this.$message({
          message: resp.data.message,
          type: "error"
        })
      })
      this.fileName = ""
    },
    home() {
      this.path = ""
      this.childrenList()
    },
    splitPath() {
      this.paths = this.path.split("/").splice(1);
    },
    handle(row,column,event,cell) {
      // console.log(row.fileName)
      if (this.dialogFormVisibleRename)
        return
      if (row.isDirectory) {
        this.addStack(this.path)
        this.path += "/" + row.fileName
        this.childrenList()
      }else {
        window.open("api/downloadFile?path=" + this.path + "&fileName=" + row.fileName) //下载文件
      }
    },
    handleDelete(row, colum, event, cell) {
      this.dialogFormVisible = false
      axios.delete("api/deleteFile", {
        params: {
          fileName: row.fileName,
          path: this.path
        }
      }).then(resp => {
        if (resp.data.code === 200) {
          this.$message({
            message: "文件删除成功",
            type: "success"
          })
        }else {
          this.$message({
            message: resp.data.message,
            type: "warning"
          })
        }
        this.childrenList()
      }).catch(resp => {
        this.$message({
          message: resp.data.message,
          type: "error"
        })
        this.childrenList()
      })
    },
    handleRename() {
      this.dialogFormVisibleRename = false
      axios.put("/api/renameFile", {
        path: this.path,
        fileName: this.fileName,
        newName: this.newName
      }).then(resp => {
        if (resp.data.code === 200) {
          this.$message({
            message: "重命名成功",
            type: "success"
          })
        }else {
          this.$message({
            message: resp.data.message,
            type: "warning"
          })
        }
        this.childrenList()
      }).catch(resp => {
        this.$message({
          message: resp.error,
          type: "error"
        })
        this.childrenList()
      })
      this.newName = "";
    },
    clickRenameButton(row) {
      this.dialogFormVisibleRename = true
      this.fileName = row.fileName
      this.newName = this.fileName
    },
    uploadSuccess() {
      this.$message({
        message: "上传成功",
        type: "success"
      })
      this.progressStatus = "success"
      this.childrenList()
      this.uploadAfter()
    },
    uploadFailure() {
      this.$message({
        message: "上传失败",
        type: "error"
      })
      this.progressStatus = "exception"
    },
    uploadExceed() {
      this.$message({
        message: "请等待当前文件上传",
        type: "warning"
      })
    },
    fileUpload(item) {
      this.uploadPercent = 0
      this.progressStatus = ""
      //上传文件的需要FormData类型;所以要转
      let formData = new window.FormData()
      formData.append('file', item.file);
      formData.append('path', this.path);
      // console.log(formData)
      this.$message({
        message: "文件上传中",
        type: "default"
      })
      axios.post("/api/upload", formData,{
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: progressEvent => {
          this.uploadPercent = (progressEvent.loaded / progressEvent.total * 100) | 0
        }
      }).then(resp => {
        if (resp.data.code === 200) {
          this.uploadSuccess()
        }else {
          this.$message({
            message: resp.data.message,
            type: "warning"
          })
          this.progressStatus = "exception"
        }
      }).catch(resp => {
        this.$message({
          message: resp.message,
          type: "error"
        })
        this.progressStatus = "exception"
      })
    },
		rowClick(row, column, event) {
			this.selectFile = row.fileName
			// console.log(row)
			row.style["background-color"] = "green"
			this.rowStyle["background-color"] = "green"
		},
		checkSelected() {
			// 检查是否选中文件，否则不能复制粘贴
			if (this.srcFile == null || this.srcPath == null) {
				return false;
			}
			return true;
  },
		copyFile() {
			this.srcFile = this.selectFile
			this.srcPath = this.path
			this.$message({
			  message: "已复制",
			  type: "info"
			})
		},
		pasteFile() {
			axios.put("api/copy", {
				srcPath: this.srcPath,
				descPath: this.path,
				filename: this.srcFile
			}).then(resp => {
				if (resp.data.code === 200) {
					this.$message({
						message: "粘贴成功",
						type: "info"
					})
					this.childrenList()
				}else {
					this.$message({
						message: resp.data.message,
						type: "warning"
					})
				}
			}).catch(resp => {
				this.$message({
					message: resp.message,
					type: "error"
				})
			})
			this.srcFile = null
			this.srcPath = null
			this.selectFile = null
		},
    jump() {
      this.$router.push("/search")
    },
    handleKeyDown(event) {
      if (event.key === "Enter") {
        if (this.focusElement === "100")
          this.childrenList()
        if (this.focusElement === "200")
          this.addDirectory()
      }
    },
    checkFileTypeIcon(event) {
      if (event.isDirectory) {
        return "el-icon-folder"
      }
    },
    checkFileTypeText(event) {
      if (event.isDirectory) {
        return "文件夹"
      }
      const type = event.fileName.slice(event.fileName.lastIndexOf(".") + 1)
      if (type === "")
        return "未知"
      return type + "文件"
    },
    uploadAfter() {
      setTimeout(() => {
        this.uploadPercent = 0;
      }, 3000) // 使得进度条消失
    },
    addStack(pa) {
      this.pathStack.push(pa)
    },
    popStack() {
      if (this.pathStack.length !== 0) {
        this.path = this.pathStack.pop()
        this.childrenList()
      }
    },
    go() {
      this.addStack(this.path)
      this.childrenList()
    }
  },
  mounted() { //进入页面时默认调用方法，相当于window.onload
    this.childrenList()
    window.addEventListener("keydown", this.handleKeyDown) //键盘监听
    const activeElement = useActiveElement()
    watch(activeElement, (el) => { // 当前焦点
      this.focusElement = el.id
    })
  },
}
</script>

<template>
  <div align="center" >
    <div align="center" style="width: 1200px">
      <div v-show="uploadPercent !== 0" style="position: fixed; width: 1200px; padding-top: 0">
        <el-progress style="margin-top: 8px;"  :percentage="uploadPercent" :status="progressStatus"></el-progress> <!-- 进度条-->
      </div>
      <br/><br/>
    <div style="border-left: 200px; float: left">
      <span>当前路径：</span>
      <span @click="home" class="link">root</span>
      <span v-for="(val, idx) in paths">
        / <span @click="childrenListByIdx(idx)" class="link">{{val}}</span>
      </span>
    </div>
		<div align="right">
      <el-button icon="el-icon-search" @click="jump"></el-button>
      <el-button :disabled="this.selectFile == null" @click="copyFile">复制</el-button>
      <el-button :disabled="this.srcPath == null" @click="pasteFile">粘贴</el-button>&nbsp;&nbsp;
      <el-upload
          class="upload-demo"
          action=""
          :http-request="fileUpload"
          :on-success="uploadSuccess"
          :on-error="uploadFailure"
          :on-exceed="uploadExceed"
          methods="POST"
          style="display: flow; float: right;"
          :show-file-list="false"
      >
        <el-button type="primary" style="display: flow; float: right;" icon="el-icon-upload2">&nbsp;上传文件到此处&nbsp;</el-button>
      </el-upload>
		</div>
<!--      <input type="file" @close="fileUpload" value="文件上传">-->
    <el-dialog title="添加文件夹" :visible.sync="dialogFormVisible">
      <el-form>
        <el-form-item label="文件夹命名">
          <el-input v-model="fileName" autocomplete="off" id="200"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addDirectory">确 定</el-button>
      </div>
    </el-dialog>
    <br/>
    <el-button @click="home" style="float: left" icon="el-icon-s-home"></el-button>&nbsp;
    <el-button @click="popStack" style="float:left;" icon="el-icon-back"></el-button>&nbsp;
    <el-button @click="backLastDirectory" icon="el-icon-top"></el-button>&nbsp;
    <el-input v-model="path" style="width: 480px" placeholder="路径" id="100"></el-input>&nbsp
    <el-button @click="go" icon="el-icon-right"></el-button>
<!--    <el-input v-model="fileName" placeholder="文件名" style="width: 280px"></el-input>&nbsp-->
    <el-button @click="
    dialogFormVisible = true
    fileName = ''
" style="float: right;" icon="el-icon-folder-add">在此处添加文件夹</el-button>

    <div>
      <el-table
          :data="children"
          style="width: 100%"
          height="741px"
          v-loading="loading"
          :default-sort="{prop: 'fileName', order: 'descending'}"
          @row-dblclick="handle"
					v-on:row-click="rowClick"
      >
			<!-- v-bind:row-style="rowStyle" -->
        <template v-if="code===200">
          <el-table-column
              prop="fileName"
              label="文件名"
              sortable
              width="300"
          >
          </el-table-column>
          <el-table-column
              label="文件类型"
          >
            <template slot-scope="scope">
              <i v-bind:class="checkFileTypeIcon(scope.row)"></i>
              <span>{{checkFileTypeText(scope.row)}}</span>
            </template>
          </el-table-column>
          <el-table-column
              prop="size"
              label="大小"
              sortable
              width="100">
            <template slot-scope="scope"> <!-- 判断数据大小以给定合适单位 -->
              <span v-if="scope.row.isDirectory">-</span>
              <span v-else-if="scope.row.size <= 1024">{{scope.row.size}} B</span>
              <span v-else-if="scope.row.size <= 1024 * 1024">{{toNumber(scope.row.size / 1024)}} KB</span>
              <span v-else-if="scope.row.size <= 1024 * 1024 * 1024">{{toNumber(scope.row.size / (1024 * 1024))}} MB</span>
              <span v-else>{{toNumber(scope.row.size / (1024 * 1024 * 1024))}} GB</span>
            </template>
          </el-table-column>
          <el-table-column
              prop="creationTime"
              label="创建时间"
              sortable
              width="180px"
              :formatter="toDateString">
          </el-table-column>
          <el-table-column
              prop="lastAccessTime"
              label="最后访问时间"
              sortable
              width="180"
              :formatter="toDateString">
          </el-table-column>
          <el-table-column
              prop="lastModifiedTime"
              label="最后修改时间"
              sortable
              width="180"
              :formatter="toDateString">
          </el-table-column>
          <el-table-column
              label="操作"
              width="140">
            <template slot-scope="scope">
              <el-popconfirm
                  title="确定删除该文件？"
                  @confirm="handleDelete(scope.row)"
                  confirm-button-type="danger"
                  cancel-button-type="info"
                  icon-color="red"
              >
                <el-button type="danger" size="small" slot="reference">删除</el-button>
              </el-popconfirm>
              &nbsp;
              <el-button slot="reference" type="text" @click="clickRenameButton(scope.row)">重命名</el-button>
              <el-dialog title="文件重命名" :visible.sync="dialogFormVisibleRename">
                <el-form>
                  当前文件：{{fileName}}
                  <el-form-item label="新文件名">
                    <el-input v-model="newName" autocomplete="off"></el-input>
                  </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                  <el-button @click="dialogFormVisibleRename = false">取 消</el-button>
                  <el-button type="primary" @click="handleRename">确 定</el-button>
                </div>
              </el-dialog>
            </template>
          </el-table-column>
        </template>
        <div slot="empty" class="empty">
          <span style="color: red">无文件</span>
        </div>
      </el-table>
    </div>
    </div>
  </div>
</template>

<style scoped>
  .link{
    color: cadetblue;
    text-underline: cadetblue;
    text-decoration: underline;
  }
  .link:hover{
    color: #050505;
    text-underline: cadetblue;
    text-decoration: underline;
  }
</style>